import { useState, useImperativeHandle } from 'react';
import { useDispatch, useSelector } from 'umi';
import styles from './index.less';
import { riskToScene } from '../constantConfig';
import { TableC, InputNumberC, TreeSelectC, IconC } from '../../../../components';
import { Form, message, Popover, Tree } from 'antd';
import uuid from 'es6-uuid';
import groupTree from '@/src/assets/busi/stressTest/groupTree.png';
import { findTitleByValue } from '../../../../utils/utils';
import { times, divide } from 'number-precision';
import { namespace } from '@/src/newModels/pressureReport/SceneTemplateSettingsM';

const editTreeData = (arr = []) => {
  arr.forEach((item) => {
    item.key = item.value;
    //  如果有子项 则继续递归，如果无子项
    if (item.children?.length) {
      // 有子项的继续
      editTreeData(item.children);
    }
  });
};
/**
 * 判断是否标签
 * id 选项的唯一key
 * arr 数组
 *
 */
const getGroupData = (id, arr = []) => {
  let temp = [];
  arr.forEach((item) => {
    if (id === item.value) {
      if (item.children?.length) {
        temp = temp.concat(item);
      }
    } else {
      // 第一级没有匹配成功 如果有子项 则继续递归，如果无子项 就是是false
      if (item.children?.length) {
        // 有子项的继续
        const childData = getGroupData(id, item.children);
        if (childData?.length) {
          temp = temp.concat(childData);
        }
      }
    }
  });
  return temp;
};

// 新增表格
const AddTableC = (props) => {
  const { id, tableData = [], showType = 'edit' } = props;
  // 暴露子组件的方法和属性 给父组件
  if (showType === 'edit')
    useImperativeHandle(props.onRef, () => ({
      addRow,
      id,
      attrs,
      submit,
    }));

  const modelState = useSelector((state) => state[namespace]);
  const { factorDictObj } = modelState; // 维度下拉
  const [form] = Form.useForm();
  const [data, setData] = useState(tableData); // 拿到表格数据 通过useState可以实时刷新视图
  const [editingKey, setEditingKey] = useState(''); // 正在编辑行的key
  // 获取attrs 用于列表展示项
  const tempData = riskToScene.filter((item) => item.riskId === id);
  const attrs = tempData[0]?.attrs || [];
  // 函数 判断是否是正在编辑的行
  const isEditing = (record) => record.key === editingKey;
  // 更新数据，操作项显示与否
  const upDateData = (key, boolFlag) => {
    const newData = [...data];
    const index = newData.findIndex((item) => key === item.key);
    if (index > -1) {
      const item = newData[index];
      newData.splice(index, 1, {
        ...item,
        isEdit: boolFlag,
      });
      setData(newData);
    }
  };
  // 提交表单数据
  const submit = () => {
    return new Promise((resolve, reject) => {
      if (editingKey !== '') {
        message.info('请先保存正在编辑的行！');
        reject();
      } else {
        resolve(data);
      }
    });
  };
  // 编辑行
  const editRow = (record) => {
    if (editingKey !== '') {
      message.info('请先保存正在编辑的行！');
      return;
    }
    setEditingKey(record.key); // 更新编辑行id 便于行 编辑还是文本展示
    for (const key in record) {
      if (Object.hasOwnProperty.call(record, key)) {
        const element = record[key];
        if (['risk1', 'risk2', 'risk3'].includes(key)) {
          //* 100 乘以100
          form.setFieldsValue({
            [key]: Number(times(element, 100).toFixed(2)),
          });
        } else {
          form.setFieldsValue({
            [key]: element,
          });
        }
      }
    }
    upDateData(record.key, true); // 更新数据 变更行的变量isEdit 便于操作项展示
  };
  // 重置下表单 否则会缓存上次的表单数据
  const reset = () => {
    form.resetFields();
  };
  // 取消
  const cancelRow = (record) => {
    if (!record.isAdd) upDateData(record.key, false); // 更新数据 变更行的变量isEdit 便于操作项展示
    else {
      // 新增的行 则需要删除
      deleteRow(record);
    }
    setEditingKey('');
    reset(); // 清空表单
  };
  // 删除行
  const deleteRow = (record) => {
    const newData = data.filter((item) => item.key !== record.key);
    setData([...newData]);
  };
  // 新增行
  const addRow = () => {
    if (editingKey !== '') {
      message.info('请先保存正在编辑的行！');
      return;
    }
    if (!attrs?.length && data?.length) {
      message.info('该因子没有对应维度，只能有一条数据！');
      return;
    }
    const newData = [...data];
    newData.unshift({
      key: uuid(16),
      isAdd: true,
      isEdit: true, // 因编辑时拿到的列表数据有延迟 所以这里就先给一个true(仅针对新增行)
    });
    setData([...newData]);
    editRow(newData[0]);
  };
  // key为当前行的唯一id
  const saveRow = async (key) => {
    try {
      const row = await form.validateFields();
      for (const i in row) {
        if (Object.hasOwnProperty.call(row, i)) {
          if (['risk1', 'risk2', 'risk3'].includes(i)) {
            // /100 除以100
            row[i] = Number(divide(row[i], 100).toFixed(2));
          }
        }
      }
      const newData = [...data];
      const index = newData.findIndex((item) => key === item.key);
      if (index > -1) {
        const item = newData[index];
        newData.splice(index, 1, {
          ...item,
          ...row,
          isAdd: false,
          isEdit: false, // 便于处理操作项
        });
        setData(newData);
        setEditingKey('');
        reset(); // 清空表单
      }
    } catch (errInfo) {
      console.log('Validate Failed:', errInfo);
    }
  };
  // 编辑表格行 设置每行表单
  const EditableCell = ({ editing, dataIndex, title, editFormType, record, index, children, ...restProps }) => {
    return (
      <td {...restProps}>
        {editing ? (
          editFormType === 'select' ? (
            <TreeSelectC
              dataIndex={dataIndex}
              initialValue={record[dataIndex]}
              rules={[
                {
                  required: true,
                },
              ]}
              switcherIcon={<img src={groupTree} style={{ marginRight: '10px', maxWidth: '12px', maxHeight: '12px' }} />}
              dataSource={factorDictObj[dataIndex]}
            />
          ) : (
            <InputNumberC
              dataIndex={dataIndex}
              min={0}
              max={100}
              unit={'%'}
              rules={[
                {
                  required: true,
                },
              ]}
            />
          )
        ) : (
          children
        )}
      </td>
    );
  };
  // 加载 columns标签组 图标
  const renderCols = (text, data = []) => {
    if ((text ?? '--') === '--') {
      return '--';
    }
    const groupData = _.cloneDeep(getGroupData(text, data));
    // treeData 需要修改为key title
    editTreeData(groupData);
    const content = (treeData) => {
      return (
        <div>
          <Tree treeData={treeData} switcherIcon={<img src={groupTree} style={{ marginRight: '10px', maxWidth: '12px', maxHeight: '12px' }} />} />
        </div>
      );
    };
    return (
      <span style={{ display: 'flex', alignItems: 'center' }}>
        {groupData?.length ? (
          <Popover content={content(groupData)} title='' mouseLeaveDelay={0.5}>
            <img src={groupTree} style={{ cursor: 'pointer', marginRight: '10px', maxWidth: '12px', maxHeight: '12px' }} />
          </Popover>
        ) : null}
        {findTitleByValue(text, data || [])}
      </span>
    );
  };
  //   attrs: ['sectype', 'bondRate', 'bondType', 'bondInvestType']
  //   资产类型、债券信用评级、债券类别、债券投资分类
  const columns = [
    {
      title: '资产类型',
      key: 'sectype',
      editable: true,
      editFormType: 'select',
      render: (text) => renderCols(text, factorDictObj.sectype),
    },
    {
      title: '债券信用评级',
      key: 'bondRate',
      editable: true,
      editFormType: 'select',
      render: (text) => renderCols(text, factorDictObj.bondRate),
    },
    {
      title: '债券类别',
      key: 'bondType',
      editable: true,
      editFormType: 'select',
      render: (text) => renderCols(text, factorDictObj.bondType),
    },
    {
      title: '债券投资分类',
      key: 'bondInvestType',
      editable: true,
      editFormType: 'select',
      render: (text) => renderCols(text, factorDictObj.bondInvestType),
    },
    {
      title: '轻度假设',
      key: 'risk1',
      type: 'rate',
      editable: true,
      isNeed: true,
      editFormType: 'inputNumber',
    },
    {
      title: '中度假设',
      key: 'risk2',
      type: 'rate',
      editable: true,
      isNeed: true,
      editFormType: 'inputNumber',
    },
    {
      title: '重度假设',
      key: 'risk3',
      type: 'rate',
      editable: true,
      isNeed: true,
      editFormType: 'inputNumber',
    },
    {
      title: '操作',
      key: 'operation',
      type: 'operate',
      isNeed: true,
      operates: [
        {
          title: '编辑',
          rules: {
            hide: {
              relation: 'or',
              items: [{ key: 'isEdit', value: [true], relation: ['='] }],
            },
          },
          onClick: (record) => {
            editRow(record);
          },
        },
        {
          title: '删除',
          rules: {
            hide: {
              relation: 'or',
              items: [{ key: 'isEdit', value: [true], relation: ['='] }],
            },
          },
          onClick: (record) => {
            deleteRow(record);
          },
        },
        {
          title: '保存',
          rules: {
            hide: {
              relation: 'or',
              items: [{ key: 'isEdit', value: [false], relation: ['='] }],
            },
          },
          onClick: (record) => {
            saveRow(record.key);
          },
        },
        {
          title: '取消',
          rules: {
            hide: {
              relation: 'or',
              items: [{ key: 'isEdit', value: [false], relation: ['='] }],
            },
          },
          onClick: (record) => {
            cancelRow(record);
          },
        },
      ],
    },
  ];
  if (showType === 'view') {
    columns.pop();
  }
  const getCols = () => {
    const arr = [];
    columns.forEach((col) => {
      if (attrs.includes(col.key)) {
        arr.push(col);
      } else {
        if (col.isNeed) {
          arr.push(col);
        }
      }
    });
    if (arr.length && showType !== 'view')
      arr.forEach((item) => {
        // 根据列多少 分一下宽度
        if (item.key === 'operation') return;
        item.width = `${(100 - 8.9) / (arr.length - 1)}%`;
      });
    return arr;
  };
  const mergedColumns = getCols().map((col) => {
    if (!col.editable) {
      // 非编辑数据 不处理 直接返回原定义
      return col;
    }
    // onCell function(record, rowIndex) 设置单元格属性，可以加一些编辑需要的属性 也就是 EditableCell 的入参
    return {
      ...col,
      onCell: (record) => ({
        record,
        editFormType: col.editFormType,
        dataIndex: col.key,
        title: col.title,
        editing: showType === 'view' ? false : isEditing(record),
      }),
    };
  });
  return (
    <div className={styles.addTable}>
      <Form form={form}>
        <TableC
          components={{
            body: {
              cell: EditableCell,
            },
          }}
          dataSource={data}
          columns={mergedColumns}
          hidePage={true}
          rowKey={'key'}
        />
      </Form>
    </div>
  );
};
export default AddTableC;
